<?php

namespace app\common\cachemodel\zlcr3;

use app\common\lib\Util;
use app\common\model\BaseCache;
use app\common\model\Recode;
use XznsTools\cache\CacheManage;

class Zlcr3ConsultChatRecordDetails extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.zlcr3_consult_chat_record_details';

    protected $cacheModel = 'voice_consult.chat_details';

    public $interceptTips = '安全巡查已介入，为保障你的权益和隐私，请遵守平台规则';

    /**
     * 获取列表数据
     * @param int $chatId
     * @param int $limit
     * @param int $maxId
     * @return array
     * @throws \Exception
     */
    public function getPageDatas(int $chatId, int $limit, int $maxId = 0)
    {
        $idsData = CacheManage::getInstance()
            ->setCacheConfig($this->cacheModel, $chatId)
            ->setPage(-1)
            ->setSort('desc')
            ->getListPageDataIds(function ($isCache = true, $sortType = 'desc') use ($chatId)
            {
                try
                {
                    $data = $this->where(['chat_id' => $chatId])->order("id {$sortType}")->column('id');

                    $resData = [];
                    foreach ($data as $id)
                    {
                        $resData[$id] = ['id' => $id];
                    }

                    return $resData;
                }
                catch (\Exception $e)
                {
                    return [];
                }
            }, 'id', 0);

        arsort($idsData['data']);
        $allIds = array_keys($idsData['data']);
        $ids = [];
        $surplusNum = 0;
        foreach ($allIds as $idItem)
        {
            if ($maxId > 0 && $idItem >= $maxId) continue;

            if (count($ids) >= $limit)
            {
                $surplusNum++;
            } else
            {
                $ids[] = $idItem;
            }
        }
        $dataList = $this->batchGetInfoByIds($ids);
        asort($ids);

        $resDataList = [];
        foreach ($ids as $idItem)
        {
            if (isset($dataList[$idItem]))
            {
                $resDataList[] = $dataList[$idItem];
            }
        }

        $resData = [
            'total' => count($allIds),
            'surplus_num' => $surplusNum,
            'data' => $resDataList
        ];

        return $resData;
    }

    /**
     * 咨询对话写入数据
     */
    public function SaveData(int $chatId, array $datas)
    {
        try
        {
            if (isset($datas['extend']) && is_array($datas['extend']))
            {
                $datas['extend'] = json_encode($datas['extend'], JSON_UNESCAPED_UNICODE);
            }
            $id = $this->insertGetId($datas);
            $datas['id'] = (int)$id;
            // list ID添加
            $this->listDataAdd($chatId, [$datas['id'] => $datas['id']]);
        }
        catch (\Exception $e)
        {
            \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . '()异常：' . $e->getMessage() . '失败信息：' . $e->getFile() . ':' . $e->getLine(), 'error', true);
            return [];
        }

        if (isset($datas['extend']))
        {
            $datas['extend'] = $datas['extend'] ? json_decode($datas['extend'], true) : [];
        }

        return $datas;
    }

    public function UpdateData(int $id, array $data)
    {
        try
        {
            if (isset($data['extend']) && is_array($data['extend']))
            {
                $data['extend'] = json_encode($data['extend'], JSON_UNESCAPED_UNICODE);
            }
            $data['update_time'] = time();

            $this->where(['id' => $id])->update($data);

            CacheManage::getInstance()->setCacheConfig($this->cacheModel, $id)->rmCache();

            return true;
        }
        catch (\Exception $e)
        {
            \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . '()异常：' . $e->getMessage() . '失败信息：' . $e->getFile() . ':' . $e->getLine(), 'error', true);
            return false;
        }
    }

    /**
     * 数据 返回样式重组
     * @param array $dataList
     * @param array $astrInfo 占星师信息
     * @param array $userInfo 用户信息
     * @param null $delayComment 待评论信息
     * @return array
     * @throws \Exception
     */
    public function userDataListResert(array $dataList, array $astrInfo, array $userInfo, &$delayComment = null)
    {
        $resData = [];
        $lastTime = 0;
        $now0Time = strtotime(date('Y-m-d')); // 今日0点时间
        foreach ($dataList as $k => $dataItem)
        {
            $createTime = '';
            if ($dataItem['create_time'] - $lastTime > 300)
            {
                $createTime = $this->timeConvert($dataItem['create_time'], $now0Time);
            }
            // $dataItem['type']  1=>APP消息 2=>用户发送消息
            $avatar = $dataItem['type'] === 1 ? $astrInfo['avatar'] : $userInfo['avatar'];
            $consultInfo = null;
            $btnInfo = null;
            $contentType = 1;
            $msgDes = $dataItem['title'];
            switch ($dataItem['data_type'])
            {
                case 1: // 普通消息
                    $content = $dataItem['content'];
                    break;
                case 2: // 图片
                    $content = $dataItem['content'];
                    $contentType = 2;
                    break;
                case 3: // 语音咨询消息
                    $msgDes = '连线咨询';
                    $content = '';
                    if ($dataItem['extend']['rtc_data']['rtc_id'] > 0)
                    {
                        $rtcInfo = (new Zlcr3ConsultChatRtcRecord())->getInfoById($dataItem['extend']['rtc_data']['rtc_id']);
                        $link = "alert_consult_question?id={$dataItem['id']}&need_auth=2";
                        switch ($rtcInfo['status'])
                        {
                            case 1:
                                $consultInfo = [
                                    'status' => 1, // 1=>申请连线中 2=>连接中 3=>连线中 4=>咨询结束
                                    'tip' => '正在发起语音咨询',
                                    'target' => 'local',
                                    'link' => $link,
                                ];
                                break;
                            case 2:
                                $consultInfo = [
                                    'status' => 2, // 1=>申请连线中 2=>连接中 3=>连线中 4=>咨询结束
                                    'tip' => '正在接通中',
                                    'target' => 'local',
                                    'link' => $link,
                                ];
                                break;
                            case 3:
                                $consultInfo = [
                                    'status' => 3, // 1=>申请连线中 2=>连接中 3=>连线中 4=>咨询结束
                                    'tip' => '连线咨询中',
                                    'target' => 'local',
                                    'link' => $link,
                                ];
                                break;
                            case 4:
                                $durationTime = Util::secondToMinute($rtcInfo['duration']);
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连接中 3=>连线中 4=>咨询结束
                                    'tip' => "连线时长 {$durationTime}，消耗{$rtcInfo['coin']}准币",
                                    'target' => 'local',
                                    'link' => "rtc_consult_detail?id={$dataItem['id']}&need_auth=2",
                                ];
                                if ($rtcInfo['is_comment'])
                                {
                                    $delayComment = null;
                                } else
                                {
                                    $delayComment = [
                                        'id' => $dataItem['id'],
                                        'duration' => $rtcInfo['duration'],
                                        'coin' => $rtcInfo['coin'],
                                        'avatar' => $astrInfo['avatar'] ?? null,
                                        'name' => $astrInfo['nickname'] ?? null,
                                    ];
                                }
                                break;
                            case 5:
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连接中 3=>连线中 4=>咨询结束
                                    'tip' => '故障挂断',
                                    'target' => 'local',
                                    'link' => 'empty',
                                ];
                                break;
                            case 6:
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连接中 3=>连线中 4=>咨询结束
                                    'tip' => $rtcInfo['type'] === 2 ? '咨询师不便接听，稍后重试' : '连线已取消', // 挂断用户  1=>用户   2=>咨询师
                                    'target' => 'local',
                                    'link' => 'empty',
                                ];
                                break;
                            default:
                        }
                    } else
                    {
                        switch ($dataItem['extend']['rtc_data']['status'])  // 1=>申请中待接听  2=>咨询师未响应  3=>咨询师拒绝  4=>连线已取消 5=>咨询师忙线中
                        {
                            case 1: // 申请中待接听
                                $consultInfo = [
                                    'status' => 1, // 1=>申请连线中 2=>连线中 3=>咨询结束
                                    'tip' => '正在发起语音咨询',
                                    'target' => 'local',
                                    'link' => "alert_consult_question?id={$dataItem['id']}&need_auth=2",
                                ];
                                break;
                            case 2: // 咨询师未响应
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连线中 3=>咨询结束
                                    'tip' => '咨询师未响应',
                                    'target' => 'local',
                                    'link' => "alert_consult_question?id=0&need_auth=2",
                                ];
                                break;
                            case 3: // 咨询师拒绝
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连线中 3=>咨询结束
                                    'tip' => '咨询师不便接听，稍后重试',
                                    'target' => 'local',
                                    'link' => "alert_consult_question?id=0&need_auth=2",
                                ];
                                break;
                            case 4: // 连线已取消
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连线中 3=>咨询结束
                                    'tip' => '连线已取消',
                                    'target' => 'local',
                                    'link' => "alert_consult_question?id=0&need_auth=2",
                                ];
                                break;
                            case 5: // 咨询师忙线中
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连线中 3=>咨询结束
                                    'tip' => '忙线中',
                                    'target' => 'local',
                                    'link' => "alert_consult_question?id=0&need_auth=2",
                                ];
                                break;
                        }
                    }
                    break;
                case 4: // 咨询问题
                    $msgDes = '我的问题已提交 —— 问题咨询';
                    $content = $dataItem['content'];
                    break;
                case 5: // 咨询问题答案
                    $msgDes = '问题已收到';
                    $content = $dataItem['content'];
                    $btnInfo = [
                        'name' => '语言连线咨询',
                        'target' => 'local',
                        'link' => "alert_consult_question?id=0&need_auth=2",
                    ];
                    break;
                default:
                    $content = '';
            }
            $data = [
                'id' => $dataItem['id'],
                'type' => $dataItem['type'] === 1 ? 2 : 1,
                'time_des' => $createTime,
                'time' => 0,
                'avatar' => $avatar,
                'msg_des' => $msgDes,
                'tags' => $dataItem['extend']['tags'] ?? [],
                'consult_info' => $consultInfo ?? null,
                'content' => $content,
                'content_type' => $contentType,
                'btn_info' => $btnInfo ?? null,
                'intercept_tips' => !empty($dataItem['extend']['intercept_tips']) ? $this->interceptTips : ''
            ];

            // 更新最后发送时间
            $lastTime = $dataItem['create_time'];
            $resData[] = $data;
        }

        return $resData;
    }

    /**
     * 数据 返回样式重组
     * @param array $dataList
     * @param array $astrInfo 占星师信息
     * @param array $userInfo 用户信息
     * @return array
     */
    public function astrDataListResert(array $dataList, array $astrInfo, array $userInfo)
    {
        $resData = [];
        $lastTime = 0;
        $now0Time = strtotime(date('Y-m-d')); // 今日0点时间
        $nowTime = time();
        $userDesStr = '';
        $recodeModel = new Recode();
        $utilModel = new Util();
        if ($userInfo && $userInfo['rid'])
        {
            $recode = $recodeModel->getRecode(['id' => $userInfo['rid']]);
            if ($recode)
            {
                $sexTxt = [
                    1 => '男生',
                    2 => '女生'
                ];
                $age = Util::getAgeByBirth($recode['year'], $recode['month'], $recode['day'], 2);
                $sex = $sexTxt[$recode['type']] ?? '未知';
                $userDesStr = '日' . $utilModel->recodeAstroShorthand($recode['sun']) . '月' . $utilModel->recodeAstroShorthand($recode['moon']) . '升' . $utilModel->recodeAstroShorthand($recode['asc']) . "·{$age}周岁·{$sex}";
            }
        }
        $zlcr3ConsultChatRtcRecordModel = new Zlcr3ConsultChatRtcRecord();
        foreach ($dataList as $k => $dataItem)
        {
            $createTime = '';
            if ($dataItem['create_time'] - $lastTime > 300)
            {
                $createTime = $this->timeConvert($dataItem['create_time'], $now0Time);
            }
            // $dataItem['type']  1=>APP消息 2=>用户发送消息
            $avatar = $dataItem['type'] === 1 ? $astrInfo['avatar'] : $userInfo['avatar'];
            $checkTime = 0;
            if ($dataItem['type'] === 1 && $nowTime - $dataItem['create_time'] < 30)
            {   // 咨询师消息
                $checkTime = 30 - ($nowTime - $dataItem['create_time']);
            }
            $msgDes = $dataItem['title'];
            $userDes = '';
            $btnInfo = null;
            $consultInfo = null;
            $contentType = 1;
            $serverSuc = 0;
            $isComment = 0;
            switch ($dataItem['data_type'])
            {
                case 1:
                    $content = $dataItem['content'];
                    break;
                case 2:
                    $content = $dataItem['content'];
                    $contentType = 2;
                    break;
                case 3:
                    $msgDes = '连线咨询';
                    $content = '';
                    if ($dataItem['extend']['rtc_data']['rtc_id'] > 0)
                    {
                        $rtcInfo = $zlcr3ConsultChatRtcRecordModel->getInfoById($dataItem['extend']['rtc_data']['rtc_id']);
                        switch ($rtcInfo['status'])
                        {
                            case 2:
                                $consultInfo = [
                                    'status' => 2, // 1=>申请连线中 2=>连接中 3=>连线中 4=>咨询结束
                                    'tip' => '正在申请连线咨询',
                                    'target' => 'local',
                                    'link' => 'empty',
                                ];
                                $btnInfo = [
                                    [
                                        'name' => '连接中',
                                        'type' => 5,
                                        'id' => $dataItem['id'],
                                    ],
                                ];
                                break;
                            case 3:
                                $consultInfo = [
                                    'status' => 3, // 1=>申请连线中 2=>连接中 3=>连线中 4=>咨询结束
                                    'tip' => '连线咨询中',
                                    'target' => 'local',
                                    'link' => 'empty',
                                ];
                                break;
                            case 4: // 4=>连麦结束
                                $durationTime = Util::secondToMinute($rtcInfo['duration']);
                                $astrEarning = (float)$rtcInfo['astr_earning'];
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连接中 3=>连线中 4=>咨询结束
                                    'tip' => "连线时长 {$durationTime}，收益{$astrEarning}元",
                                    'target' => 'local',
                                    'link' => 'empty',
                                ];
                                $serverSuc = 1;
                                $isComment = !empty($dataItem['extend']['rtc_data']['is_comment']) ? 1 : 0;
                                $btnInfo = [
                                    [
                                        'name' => '查看记录',
                                        'type' => 4,
                                        'id' => $dataItem['id'],
                                    ],
                                ];
                                break;
                            case 5: // 5=>故障挂断
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连接中 3=>连线中 4=>咨询结束
                                    'tip' => '故障挂断',
                                    'target' => 'local',
                                    'link' => 'empty',
                                ];
                                break;
                            case 6: // 6=>取消连麦（连接中挂断
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连接中 3=>连线中 4=>咨询结束
                                    'tip' => '连线已取消',
                                    'target' => 'local',
                                    'link' => 'empty',
                                ];
                                break;
                        }
                    } else
                    {
                        switch ($dataItem['extend']['rtc_data']['status'])  // 1=>申请中待接听  2=>咨询师未响应  3=>咨询师拒绝  4=>连线已取消 5=>咨询师忙线中
                        {
                            case 1: // 申请中待接听
                                $consultInfo = [
                                    'status' => 1, // 1=>申请连线中 2=>连线中 3=>咨询结束
                                    'tip' => '正在申请连线咨询',
                                    'target' => 'local',
                                    'link' => 'empty',
                                ];
                                $btnInfo = [
                                    [
                                        'name' => '接受连线',
                                        'type' => 2,
                                        'id' => $dataItem['id'],
                                    ], [
                                        'name' => '拒绝',
                                        'type' => 3,
                                        'id' => $dataItem['id'],
                                    ],
                                ];
                                break;
                            case 2: // 咨询师未响应
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连线中 3=>咨询结束
                                    'tip' => '咨询师未响应',
                                    'target' => 'local',
                                    'link' => 'empty',
                                ];
                                break;
                            case 3: // 咨询师拒绝
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连线中 3=>咨询结束
                                    'tip' => '咨询师拒绝连线',
                                    'target' => 'local',
                                    'link' => 'empty',
                                ];
                                break;
                            case 4: // 连线已取消
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连线中 3=>咨询结束
                                    'tip' => '连线已取消',
                                    'target' => 'local',
                                    'link' => 'empty',
                                ];
                                break;
                            case 5: // 咨询师忙线中
                                $consultInfo = [
                                    'status' => 4, // 1=>申请连线中 2=>连线中 3=>咨询结束
                                    'tip' => '忙线中',
                                    'target' => 'local',
                                    'link' => 'empty',
                                ];
                                break;
                        }
                    }
                    break;
                case 4: // 咨询问题
                    $msgDes = '我的问题已提交';
                    $content = $dataItem['content'];
                    $userDes = $userDesStr;
                    if (!isset($dataItem['extend']['answer_id']))
                    {
                        $btnInfo[] = [
                            'name' => '回复问题',
                            'type' => 1,
                            'id' => $dataItem['id'],
                        ];
                    }
                    break;
                case 5: // 咨询问题答案
                    $msgDes = '';
                    $content = $dataItem['content'];
                    break;
                default:
                    $content = '';
            }
            $data = [
                'id' => $dataItem['id'],
                'type' => $dataItem['type'],
                'time_des' => $createTime,
                'time' => $checkTime,
                'avatar' => $avatar,
                'msg_des' => $msgDes,
                'tags' => $dataItem['extend']['tags'] ?? [],
                'consult_info' => $consultInfo,
                'content' => $content,
                'content_type' => $contentType,
                'btn_info' => $btnInfo ?? null,
                'user_des' => $userDes,
                'server_suc' => $serverSuc,
                'is_comment' => $isComment,
            ];

            // 更新最后发送时间
            $lastTime = $dataItem['create_time'];
            $resData[] = $data;
        }

        return $resData;
    }

    /**
     * @param array $ids
     * @param array|null $type
     * @param string $sortType
     * @return array
     */
    public function getInfoByIdsInData($ids, $type, $sortType)
    {
        try
        {
            // 获取未删除 的数据
            $data = $this
                ->where(['id' => ['in', $ids]])
                ->column('id,uid,chat_id,astr_id,type,title,content,data_type,extend,pid,create_time,update_time', 'id');
        }
        catch (\Exception $e)
        {
            $data = [];
        }

        return $data;
    }

    public function batchGetInfoByIds($cids, $field = [])
    {
        $resData = parent::batchGetInfoByIds($cids, $field);

        return $this->dataInit($resData);
    }

    /**
     * 数据初始化
     * @param array $data
     * @return array
     */
    public function dataInit(array $data)
    {
        foreach ($data as $index => $itemData)
        {
            $data[$index] = arrayKeyData2int($itemData, ['id', 'uid', 'chat_id', 'astr_id', 'type', 'data_type', 'pid', 'create_time', 'update_time']);

            if (isset($itemData['extend']))
            {
                $data[$index]['extend'] = $itemData['extend'] ? json_decode($itemData['extend'], true) : [];
            }
        }

        return $data;
    }

    /**
     * 时间转换
     * @param int $time 待转换的时间
     * @param int $now0Time 今日零点时间
     * @return string
     */
    public function timeConvert(int $time, int $now0Time)
    {
        $t = $now0Time - $time;
        if ($t <= 0)
        {
            $timeStr = date('H:i', $time);
        } elseif ($t <= 86400)
        {
            $timeStr = date('昨日 H:i', $time);
        } else
        {
            $timeStr = date('m-d H:i', $time);
        }

        return $timeStr;
    }

    /**
     * 获取 用户 今天发送咨询消息数量
     */
    public function getUserConsultMsgNumByToday($uid)
    {
        $timeDate = date('Ymd');
        return CacheManage::getInstance()->setCacheConfig($this->cacheModel)
            ->setCacheKeyDetail('today_chat_num', $timeDate . ':' . $uid)
            ->getDataAndSet(function () use ($uid)
            {
                try
                {
                    $dataList = $this->where(['uid' => $uid, 'type' => 2, 'data_type' => ['in', [1, 2]]])->whereTime('create_time', 'today')->group('astr_id')->column('count(astr_id)', 'astr_id');

                    $data = [0 => 0];

                    foreach ($dataList as $astrId => $num)
                    {
                        $data[$astrId] = $num;
                    }

                    return $data;
                }
                catch (\Exception $e)
                {
                    \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . '()异常：' . $e->getMessage() . '失败信息：' . $e->getFile() . ':' . $e->getLine(), 'error', true);
                    $data = [0 => 0];
                }
                return $data;
            }, [], 'today_chat_num');
    }

    /**
     * 用户 发送 咨询师 消息 自增
     * @param $uid
     * @param $astrId
     * @return void
     * @throws \Exception
     */
    public function setUserConsultMsgAstrNumByTodayInc($uid, $astrId)
    {
        (new Zlcr3UserConsultInfo())->updateData($uid, [
            'num' => $this->raw('num +1'),
        ]);
        $timeDate = date('Ymd');
        CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('today_chat_num', $timeDate . ':' . $uid)->setCacheInc($astrId, 'today_chat_num');
    }

    /**
     * 获取 用户 今天发送咨询消息数量
     * @param int $uid
     * @param int $astrId
     * @return array
     * @throws \Exception
     */
    public function getUserConsultAstrMsgNumByTodayEx(int $uid, int $astrId): array
    {
        $data = $this->getUserConsultMsgNumByToday($uid);

        $num = array_sum($data);

        $maxNum = (new Zlcr3UserConsultInfo())->getUserMaxSendNum($uid);

        return [
            'total' => max(15 - $num, 0),  // 今天剩余还能发送咨询问题总数
            'num' => max(5 - ($data[$astrId] ?? 0), 0),    // 今日 还能 向该占星师发送问题总数
            'max_num' => $maxNum, // 一共还能 咨询问题数
        ];
    }
}
